home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 24 / CU Amiga Magazine's Super CD-ROM 24 (1998)(EMAP Images)(GB)(Track 1 of 2)[!][issue 1998-07].iso / CUCD / Programming / SWI / source / src / pl-table.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-08-07  |  4.5 KB  |  218 lines

  1. /*  $Id: pl-table.c,v 1.14 1997/08/07 07:58:45 jan Exp $
  2.  
  3.     Copyright (c) 1990 Jan Wielemaker. All rights reserved.
  4.     See ../LICENCE to find out about your rights.
  5.     jan@swi.psy.uva.nl
  6.  
  7.     Purpose: generic support for (numeric) hashTables
  8. */
  9.  
  10. /*#define O_DEBUG 1*/
  11. #include "pl-incl.h"
  12.  
  13. /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  14. Anonymous hash-tables.  This  is  rather  straightforward.   A  peculiar
  15. thing  on these and a number of dedicated hashtables build in the system
  16. is that the last symbol of  a  specific  hash  value  is  not  the  NULL
  17. pointer,  but  a reference pointer to the next entry.  This allows us to
  18. enumerate  all  entries  of  the  table  with  only  one   word   status
  19. information.   This  is  more  efficient  and  simple to handle with the
  20. interface for non-deterministic C functions (current_predicate/2, ...).
  21. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  22.  
  23. static void
  24. allocHTableEntries(Table ht)
  25. { int n;
  26.   Symbol *p;
  27.  
  28.   ht->entries = allocHeap(ht->buckets * sizeof(Symbol));
  29.  
  30.   for(n=0, p = &ht->entries[0]; n < ht->buckets-1; n++, p++)
  31.     *p = makeTableRef(p+1);
  32.   *p = (Symbol) NULL;
  33. }
  34.  
  35.  
  36. Table
  37. newHTable(int buckets)
  38. { Table ht;
  39.  
  40.   ht = (Table) allocHeap(sizeof(struct table));
  41.   ht->buckets = buckets;
  42.   ht->size    = 0;
  43.   ht->locked  = 0;
  44.  
  45.   allocHTableEntries(ht);
  46.   return ht;
  47. }
  48.  
  49.  
  50. void
  51. destroyHTable(Table ht)
  52. { clearHTable(ht);
  53.   freeHeap(ht->entries, ht->buckets * sizeof(Symbol));
  54.   freeHeap(ht, sizeof(struct table));
  55. }
  56.  
  57.  
  58. #if O_DEBUG || O_HASHSTAT
  59. #define HASHSTAT(c) c
  60. static int lookups;
  61. static int cmps;
  62.  
  63. void
  64. exitTables(int status, void *arg)
  65. { Sdprintf("hashstat: Anonymous tables: %d lookups using %d compares\n",
  66.        lookups, cmps);
  67. }
  68. #else
  69. #define HASHSTAT(c)
  70. #endif /*O_DEBUG*/
  71.  
  72.  
  73. void
  74. initTables()
  75. { HASHSTAT(PL_on_halt(exitTables, NULL));
  76. }
  77.  
  78.  
  79. Symbol
  80. lookupHTable(Table ht, Void name)
  81. { Symbol s = ht->entries[pointerHashValue(name, ht->buckets)];
  82.  
  83.   HASHSTAT(lookups++);
  84.   for(;s && !isTableRef(s); s = s->next)
  85.   { HASHSTAT(cmps++);
  86.     if (s->name == (word)name)
  87.     { DEBUG(9, Sdprintf("lookupHTable(0x%x, 0x%x --> 0x%x\n",
  88.             ht, name, s->value));
  89.       return s;
  90.     }
  91.   }
  92.  
  93.   DEBUG(9, Sdprintf("lookupHTable(0x%x, 0x%x --> FAIL\n", ht, name));
  94.   return (Symbol) NULL;
  95. }
  96.  
  97.  
  98. static void
  99. rehashHTable(Table ht)
  100. { Symbol *oldtab  = ht->entries;
  101.   int    oldbucks = ht->buckets;
  102.   Symbol s, n;
  103.   int done = 0;
  104.   int i = 0;
  105.  
  106.   startCritical;
  107.   ht->buckets *= 2;
  108.   allocHTableEntries(ht);
  109.  
  110.   DEBUG(1, Sdprintf("Rehashing table 0x%x to %d entries\n",
  111.             ht, ht->buckets));
  112.  
  113.   for(s = oldtab[0]; s; s = n)
  114.   { int v;
  115.  
  116.     while( isTableRef(s) )
  117.     { s = unTableRef(Symbol, s);
  118.       assert(s == oldtab[++i]);
  119.       if ( !s )
  120.     goto out;
  121.     }
  122.     done++;
  123.     n = s->next;
  124.     v = pointerHashValue(s->name, ht->buckets);
  125.     s->next = ht->entries[v];
  126.     ht->entries[v] = s;
  127.   }
  128.  
  129. out:
  130.   assert(done == ht->size);
  131.   freeHeap(oldtab, oldbucks * sizeof(Symbol));
  132.   endCritical;
  133. }
  134.  
  135.  
  136. bool
  137. addHTable(Table ht, Void name, Void value)
  138. { Symbol s;
  139.   int v = pointerHashValue(name, ht->buckets);
  140.  
  141.   if (lookupHTable(ht, name) != (Symbol) NULL)
  142.     fail;
  143.   s = (Symbol) allocHeap(sizeof(struct symbol));
  144.   s->name = (word)name;
  145.   s->value = (word)value;
  146.   s->next = ht->entries[v];
  147.   ht->entries[v] = s;
  148.   ht->size++;
  149.   DEBUG(9, Sdprintf("addHTable(0x%x, 0x%x, 0x%x) --> size = %d\n",
  150.             ht, name, value, ht->size));
  151.  
  152.   if ( ht->buckets * 2 < ht->size && !ht->locked )
  153.     rehashHTable(ht);
  154.  
  155.   succeed;
  156. }  
  157.  
  158.  
  159. /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  160. Note: s must be in the table!
  161. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  162.  
  163. void
  164. deleteSymbolHTable(Table ht, Symbol s)
  165. { int v = pointerHashValue(s->name, ht->buckets);
  166.   Symbol *h = &ht->entries[v];
  167.  
  168.   for( ; *h != s; h = &(*h)->next )
  169.   { if ( *h == s )
  170.     { *h = (*h)->next;
  171.  
  172.       freeHeap(s, sizeof(struct symbol));
  173.       ht->size--;
  174.  
  175.       return;
  176.     }
  177.   }
  178. }
  179.  
  180.  
  181. Symbol
  182. nextHTable(Table ht, Symbol s)
  183. { s = s->next;
  184.   while(s != (Symbol) NULL && isTableRef(s) )
  185.     s = unTableRef(Symbol, s);
  186.  
  187.   return s;
  188. }
  189.  
  190. Symbol
  191. firstHTable(Table ht)
  192. { Symbol s = ht->entries[0];
  193.  
  194.   while(s != (Symbol) NULL && isTableRef(s) )
  195.     s = unTableRef(Symbol, s);
  196.  
  197.   return s;
  198. }  
  199.  
  200. void
  201. clearHTable(Table ht)
  202. { int n;
  203.   Symbol s;
  204.  
  205.   for(n=0; n < ht->buckets; n++)
  206.   { s = ht->entries[n];
  207.     while(s && !isTableRef(s))
  208.     { Symbol q = s->next;
  209.       freeHeap(s, sizeof(struct symbol));
  210.       s = q;
  211.     }
  212.     ht->entries[n] = s;
  213.   }
  214.  
  215.   ht->size = 0;
  216. }
  217.  
  218.